import random
from flask import request
from flask_socketio import SocketIO, emit
from threading import Event
import time
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("PLC-WebSocket-Service")

# 全局变量
STOP_EVENT = Event()

# 测试过程参数
TEST_PARAMS = {
    "initial_voltage": 0,  # 起始电压
    "first_withstand": 303,  # 第一阶段耐压值
    "second_withstand": 242,  # 第二阶段耐压值
    "ramp_up_time": 10,  # 升压时间(秒)
    "ramp_down_time": 5,  # 降压时间(秒)
    "withstand_time": 60,  # 耐压时间(秒)
}

# 当前测试状态
current_state = "idle"
current_voltage = 0
test_start_time = 0
state_start_time = 0

# 存储当前运行的测试任务
current_test_task = None


def init_plc_websocket(socketio):
    
    def continuous_test_process():
        """持续执行测试过程"""
        global current_state, current_voltage, test_start_time, state_start_time

        while not STOP_EVENT.is_set():
            logger.info("开始模拟变压器测试过程")
            test_start_time = time.time()

            # 1. 升压阶段 (0 -> 303)
            current_state = "ramp_up"
            state_start_time = time.time()
            logger.info("开始升压阶段: 0V -> 303V")

            ramp_up_duration = TEST_PARAMS["ramp_up_time"]
            target_voltage = TEST_PARAMS["first_withstand"]

            # 持续发送数据直到升压完成
            while not STOP_EVENT.is_set():
                elapsed = time.time() - state_start_time
                progress = min(1.0, elapsed / ramp_up_duration)
                current_voltage = progress * target_voltage

                # 发送数据
                emit_test_data()

                # 检查是否完成升压
                if progress >= 1.0:
                    break

                time.sleep(1)  # 每秒发送一次数据

            if STOP_EVENT.is_set():
                return

            # 2. 第一阶段耐压 (303V, 60秒)
            current_state = "withstand_1"
            state_start_time = time.time()
            current_voltage = target_voltage
            logger.info(f"开始第一阶段耐压: {target_voltage}V, 60秒")

            withstand_end_time = state_start_time + TEST_PARAMS["withstand_time"]
            # 持续发送数据直到耐压结束
            while not STOP_EVENT.is_set():
                emit_test_data()

                # 检查是否完成耐压
                if time.time() >= withstand_end_time:
                    break

                time.sleep(1)  # 每秒发送一次数据

            if STOP_EVENT.is_set():
                return

            # 3. 第一次降压 (303 -> 242)
            current_state = "ramp_down_1"
            state_start_time = time.time()
            logger.info("开始第一次降压: 303V -> 242V")

            ramp_down_duration = TEST_PARAMS["ramp_down_time"]
            start_voltage = current_voltage
            target_voltage = TEST_PARAMS["second_withstand"]

            # 持续发送数据直到降压完成
            while not STOP_EVENT.is_set():
                elapsed = time.time() - state_start_time
                progress = min(1.0, elapsed / ramp_down_duration)
                current_voltage = (
                    start_voltage - (start_voltage - target_voltage) * progress
                )

                emit_test_data()

                # 检查是否完成降压
                if progress >= 1.0:
                    break

                time.sleep(1)  # 每秒发送一次数据

            if STOP_EVENT.is_set():
                return

            # 4. 第二阶段耐压 (242V, 60秒)
            current_state = "withstand_2"
            state_start_time = time.time()
            current_voltage = target_voltage
            logger.info(f"开始第二阶段耐压: {target_voltage}V, 60秒")

            withstand_end_time = state_start_time + TEST_PARAMS["withstand_time"]
            # 持续发送数据直到耐压结束
            while not STOP_EVENT.is_set():
                emit_test_data()

                # 检查是否完成耐压
                if time.time() >= withstand_end_time:
                    break

                time.sleep(1)  # 每秒发送一次数据

            if STOP_EVENT.is_set():
                return

            # 5. 第二次降压 (242 -> 0)
            current_state = "ramp_down_2"
            state_start_time = time.time()
            logger.info("开始第二次降压: 242V -> 0V")

            ramp_down_duration = TEST_PARAMS["ramp_down_time"]
            start_voltage = current_voltage

            # 持续发送数据直到降压完成
            while not STOP_EVENT.is_set():
                elapsed = time.time() - state_start_time
                progress = min(1.0, elapsed / ramp_down_duration)
                current_voltage = start_voltage * (1 - progress)

                emit_test_data()

                # 检查是否完成降压
                if progress >= 1.0:
                    break

                time.sleep(1)  # 每秒发送一次数据

            if STOP_EVENT.is_set():
                return

            # 测试完成
            current_state = "completed"
            current_voltage = 0
            logger.info("测试过程完成")

            # 测试完成后继续发送几次数据
            for _ in range(5):
                emit_test_data()
                time.sleep(1)

            # 重置状态，准备下一轮测试
            current_state = "idle"
            time.sleep(2)  # 等待2秒后重新开始测试

    def emit_test_data():
        """发送测试数据到客户端"""
        global current_voltage, current_state

        # 根据状态生成不同的局放值
        if current_state == "ramp_up":
            # 升压过程中局放值逐渐增加
            release1 = 1.0 + (current_voltage / 303) * 2.0 + random.uniform(-0.1, 0.1)
            release2 = 0.1 + (current_voltage / 303) * 0.4 + random.uniform(-0.05, 0.05)
        elif current_state.startswith("withstand"):
            # 耐压过程中局放值相对稳定，但有轻微波动
            release1 = 3.0 + random.uniform(-0.2, 0.2)
            release2 = 0.5 + random.uniform(-0.1, 0.1)
        elif current_state.startswith("ramp_down"):
            # 降压过程中局放值逐渐减少
            release1 = 1.0 + (current_voltage / 303) * 2.0 + random.uniform(-0.1, 0.1)
            release2 = 0.1 + (current_voltage / 303) * 0.4 + random.uniform(-0.05, 0.05)
        else:
            # 其他状态
            release1 = random.uniform(1.0, 3.0)
            release2 = random.uniform(0.1, 0.5)

        # 确保局放值在合理范围内
        release1 = max(0.5, min(5.0, release1))
        release2 = max(0.05, min(1.0, release2))

        data = {
            "voltage": int(current_voltage),
            "release1": round(release1, 2),
            "release2": round(release2, 2),
            "frontSwitch": True,
            "endSwitch": True,
            "dischargeVoltage": TEST_PARAMS["second_withstand"],
            "withstandVoltage": TEST_PARAMS["first_withstand"],
            "state": current_state,
            "time": int(time.time() * 1000),
        }

        socketio.emit("plc_update", data, namespace="/plc")
        logger.info(f"发送数据: {data}")

    @socketio.on("connect", namespace="/plc")
    def handle_connect():
        """处理客户端连接"""
        global current_test_task
        logger.info(f"客户端连接，SID: {request.sid}")

        # 发送当前状态
        emit_test_data()

    @socketio.on("disconnect", namespace="/plc")
    def handle_disconnect():
        """处理客户端断开"""
        logger.info(f"客户端断开，SID: {request.sid}")

    def start_background_test():
        """启动后台测试任务"""
        global current_test_task
        print("启动后台测试任务, plc 服务")
        # 启动测试任务
        current_test_task = socketio.start_background_task(continuous_test_process)

    # 程序启动时就开始推送测试数据
    start_background_test()
